﻿using Newtonsoft.Json.Linq;
using reactiveBT.BT.Node;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace reactiveBT.BT
{
    public class Nodefactory
    {
        #region singleton

        #endregion
        public delegate BTNode Creator(JObject jsonObject);
        private static Dictionary<string, Creator> nodeCreators;
        public static Dictionary<string, Creator> NodeCreators
        {
            get
            {
                if (nodeCreators == null)
                {
                    nodeCreators = new Dictionary<string, Creator>();
                    #region Composite
                    nodeCreators.Add("Root", CreateRoot);
                    nodeCreators.Add("SubRoot", CreateRoot);
                    nodeCreators.Add("Parallel", CreateParallel);
                    nodeCreators.Add("RandomRoot", CreateRandomRoot);
                    nodeCreators.Add("Repeat", CreateRepeat);
                    nodeCreators.Add("Selector", CreateSelector);
                    nodeCreators.Add("Sequence", CreateSequence);
                    #endregion
                    #region Task
                    nodeCreators.Add("Log",CreateLog);
                    nodeCreators.Add("Wait", CreateWait);
                    nodeCreators.Add("Terminate", CreateTerminate);
                    #endregion
                    #region Decorator
                    nodeCreators.Add("Success",CreateSuccess);
                    nodeCreators.Add("Failure",CreateFailure);
                    nodeCreators.Add("Inverter",CreateInverter);
                    #endregion
                }
                return nodeCreators;
            }
        }
        #region Composites
        /// <summary>
        /// 创建根节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <returns></returns>
        public static Root CreateRoot(JObject jsonObject)
        {
            return new Root();
        }
        /// <summary>
        /// 创建并行节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <returns></returns>
        public static Parallel CreateParallel(JObject jsonObject)
        {
            return new Parallel();
        }
        /// <summary>
        /// 创建随机节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <param name="weight">权重数组</param>
        /// <returns></returns>
        public static RandomRoot CreateRandomRoot(JObject jsonObject)
        {
            var weight = jsonObject.GetValue("weight").ToObject<int[]>();
            return new RandomRoot(weight);
        }
        /// <summary>
        /// 创建重复节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <param name="count">循环次数</param>
        /// <returns></returns>
        public static Repeat CreateRepeat(JObject jsonObject)
        {
            var count = jsonObject.GetValue("count").ToObject<int>();
            return new Repeat(count);
        }
        /// <summary>
        /// 创建选择节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <param name="successCount">子节点成功次数</param>
        /// <returns></returns>
        public static Selector CreateSelector(JObject jsonObject)
        {
            var successCount = jsonObject.GetValue("successCount").ToObject<int>();
            return new Selector(successCount);
        }
        /// <summary>
        /// 创建顺序节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <param name="failureCount">子节点失败次数</param>
        /// <returns></returns>
        public static Sequence CreateSequence(JObject jsonObject)
        {
            var failureCount = jsonObject.GetValue("failureCount").ToObject<int>();
            return new Sequence(failureCount);
        }
        #endregion
        #region Tasks
        /// <summary>
        /// 创建日志Log节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <param name="logmsg">输出信息</param>
        /// <returns></returns>
        public static BT.Action CreateLog(JObject jsonObject)
        {
            var logmsg = jsonObject.GetValue("logmsg").ToObject<string>();
            return new BT.Action((BTid) => { Console.WriteLine(logmsg); });
        }
        /// <summary>
        /// 创建等待节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <param name="time">等待时间</param>
        /// <returns></returns>
        public static CoAction CreateWait(JObject jsonObject)
        {
            var time = jsonObject.GetValue("time").ToObject<float>();
            return new CoAction(() => { Console.WriteLine("finish Wait"); },time);
        }
        /// <summary>
        /// 创建终止节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <returns></returns>
        public static Terminate CreateTerminate(JObject jsonObject)
        {
            return new Terminate();
        }
        #endregion
        #region Decorator
        /// <summary>
        /// 创建成功修饰节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <returns></returns>
        public static Success CreateSuccess(JObject jsonObject)
        {
            return new Success();
        }
        /// <summary>
        /// 创建失败修饰节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <returns></returns>
        public static Failure CreateFailure(JObject jsonObject)
        {
            return new Failure();
        }
        /// <summary>
        /// 创建反转修饰节点
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <returns></returns>
        public static Inverter CreateInverter(JObject jsonObject)
        {
            return new Inverter();
        }
        #endregion
    }
}
